package com.study.studyroom.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.study.studyroom.entity.bo.OrderBo;
import com.study.studyroom.entity.bo.RoomBo;
import com.study.studyroom.entity.domain.RoomOrder;
import com.study.studyroom.entity.domain.User;
import com.study.studyroom.entity.enums.RequestResultEnum;
import com.study.studyroom.entity.enums.UnitTypeEnum;
import com.study.studyroom.entity.exception.GlobalException;
import com.study.studyroom.entity.vo.Condition;
import com.study.studyroom.entity.vo.order.OrderSearchVo;
import com.study.studyroom.entity.vo.order.OrderVo;
import com.study.studyroom.mapper.OrderMapper;
import com.study.studyroom.mapper.RoomMapper;
import com.study.studyroom.mapper.UserMapper;
import com.study.studyroom.service.OrderService;
import com.study.studyroom.utils.PriceUtil;
import com.study.studyroom.utils.TimeUtil;
import com.study.studyroom.utils.TokenUtil;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Objects;

@Service
@AllArgsConstructor
public class OrderServiceImpl extends BaseService implements OrderService {
    private final OrderMapper orderMapper;
    private final RoomMapper roomMapper;

    private final UserMapper userMapper;
    @Override
    @Transactional
    public int createOrder(OrderVo orderVo) {
        if (orderVo==null|| StringUtils.isBlank(orderVo.getToken())){
            throw new GlobalException(RequestResultEnum.CUSTOM_PARAM_CHECK_FAILED);
        }
        String userIdByToken = TokenUtil.getUserIdByToken(orderVo.getToken());
        User user = this.selectById(userMapper, Integer.parseInt(userIdByToken));
        RoomBo roomBo = roomMapper.getRoomBoById(orderVo.getRoomId());
        Date startTime = TimeUtil.stringToDate(orderVo.getStartTime());
        Date endTime = TimeUtil.stringToDate(orderVo.getEndTime());
        BigDecimal price = PriceUtil.getPrice(roomBo, startTime, endTime);
        if (user.getBalance().compareTo(price)<0){
            throw new GlobalException(RequestResultEnum.USER_NO_MONEY);
        }
        user.setBalance(user.getBalance().subtract(price));
        userMapper.updateById(user);
        RoomOrder roomOrder = new RoomOrder();
        BeanUtils.copyProperties(orderVo,roomOrder);
        roomOrder.setId((int) System.currentTimeMillis());
        roomOrder.setUserId(Integer.valueOf(userIdByToken));
        roomOrder.setRoomId(orderVo.getRoomId());
        roomOrder.setPrice(price);
        roomOrder.setStartTime(startTime);
        roomOrder.setEndTime(endTime);
        return this.insert(orderMapper, roomOrder);
    }

    @Override
    public IPage<OrderBo> getOrder(Condition<OrderSearchVo> condition) {
        OrderSearchVo queryInfo = condition.getQueryInfo();
        if (queryInfo==null||StringUtils.isBlank(queryInfo.getToken())){
            throw new GlobalException(RequestResultEnum.CUSTOM_PARAM_CHECK_FAILED);
        }
        Page<?> page = Page.of(condition.getPageIndex(), condition.getPageSize());
        String token = queryInfo.getToken();
        String roleIdByToken = TokenUtil.getRoleIdByToken(token);

        if (Objects.equals(roleIdByToken,"2")){
            queryInfo.setUserId(null);
        }else{
            queryInfo.setUserId(TokenUtil.getUserIdByToken(token));
        }
        if (StringUtils.isNotBlank(queryInfo.getUseTime())){
            queryInfo.setTime(TimeUtil.stringToDate(queryInfo.getUseTime()));
        }
        if (StringUtils.isBlank(queryInfo.getRoomId())){
            queryInfo.setRoomId(null);
        }
        return orderMapper.getOrder(page, queryInfo);
    }

    @Override
    @Transactional
    public OrderBo updateOrderStatus(String orderId) {
        RoomOrder roomOrder = this.selectById(orderMapper, Integer.parseInt(orderId));
        //如果提前一天就不能退款
        if (roomOrder.getStartTime().getTime()-System.currentTimeMillis()< UnitTypeEnum.DAY.getFormula()){
            throw new GlobalException(RequestResultEnum.TIME_LATER);
        }
        User user = this.selectById(userMapper,roomOrder.getUserId());
        user.setBalance(user.getBalance().add(roomOrder.getPrice()));
        userMapper.updateById(user);
        this.updateDataStatusById(orderMapper,roomOrder);
        OrderBo orderBo = new OrderBo();
        BeanUtils.copyProperties(roomOrder,orderBo);
        return orderBo;
    }
}
